home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / Technical Documentation / develop / develop Issue 24 / develop Issue 24 code / Scriptable Database 1.0a15 / Base / Int64.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-19  |  16.3 KB  |  525 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Int64.h
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    xxx put writers here xxx
  7.  
  8.     Copyright:    © 1994-1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.          <2>     3/20/95    andy    
  11. */
  12.  
  13. #ifndef Int64_h
  14. #define Int64_h
  15.  
  16. #ifndef REZ
  17.  
  18. //
  19. // For SInt64
  20. //
  21. #include <Types.h>
  22.  
  23. // •ga
  24. #define typeInt64        'in64'
  25.  
  26. class TIcon;
  27. class Int64;
  28.  
  29. enum 
  30.     {
  31.     kInt64CanNotFitIn32Bits = 0x7FFFFFFF,
  32.     
  33.     kRemoveSize                =    true,
  34.     kDontRemoveSize            =    false,
  35.  
  36.     typeOtherIsInt64        = 0,
  37.     typeOtherIsInt            = 128,
  38.     typeOtherIsULong         = 64,
  39.     typeOtherIsLong            = 32,
  40.     typeMask                = typeOtherIsInt64 | typeOtherIsInt | typeOtherIsULong | typeOtherIsLong,
  41.     
  42.     verbMask                = 0xF,
  43.     verbAdd                    = 0,
  44.     verbSubtract            = 1,
  45.     verbMultiply            = 2,
  46.     verbDivide                = 3,
  47.     verbShiftRight            = 4,
  48.     verbShiftLeft            = 5,
  49.     verbBitAnd                = 6,
  50.     verbAssign                = 8,
  51.  
  52.     
  53.     cmpMask                    = verbMask,
  54.     cmpNotEqual                = 0,
  55.     cmpEqual                = 1,
  56.     cmpGreaterOrEqual        = 2,
  57.     cmpLess                    = 3,
  58.     cmpLessOrEqual            = 4,
  59.     cmpGreater                = 5,
  60.  
  61.     opAssignInt64                = verbAssign             | typeOtherIsInt64,
  62.     opAddInt64                    = verbAdd                 | typeOtherIsInt64,
  63.     opSubtractInt64                = verbSubtract             | typeOtherIsInt64,
  64.     opMultiplyInt64                = verbMultiply             | typeOtherIsInt64,
  65.     opDivideInt64                = verbDivide             | typeOtherIsInt64,
  66.     opShiftRightInt64            = verbShiftRight         | typeOtherIsInt64,
  67.     opShiftLeftInt64            = verbShiftLeft         | typeOtherIsInt64,
  68.  
  69.     opAssignLong                = verbAssign             | typeOtherIsLong,
  70.     opAddLong                    = verbAdd                 | typeOtherIsLong,
  71.     opSubtractLong                = verbSubtract             | typeOtherIsLong,
  72.     opMultiplyLong                = verbMultiply             | typeOtherIsLong,
  73.     opDivideLong                = verbDivide             | typeOtherIsLong,
  74.     opShiftRightLong            = verbShiftRight         | typeOtherIsLong,
  75.     opShiftLeftLong                = verbShiftLeft         | typeOtherIsLong,
  76.  
  77.     opAssignUnsignedLong        = verbAssign             | typeOtherIsULong,
  78.     opAddUnsignedLong            = verbAdd                 | typeOtherIsULong,
  79.     opSubtractUnsignedLong        = verbSubtract             | typeOtherIsULong,
  80.     opMultiplyUnsignedLon        = verbMultiply             | typeOtherIsULong,
  81.     opDivideUnsignedLong        = verbDivide             | typeOtherIsULong,
  82.     
  83.     opAssignInt                    = verbAssign             | typeOtherIsInt,
  84.     opAddInt                    = verbAdd                 | typeOtherIsInt,
  85.     opSubtractInt                = verbSubtract             | typeOtherIsInt,
  86.     opMultiplyInt                = verbMultiply             | typeOtherIsInt,
  87.     opDivideInt                    = verbDivide             | typeOtherIsInt,
  88.  
  89.     cmpNotEqualInt64            = cmpNotEqual             | typeOtherIsInt64,
  90.     cmpEqualInt64                = cmpEqual                 | typeOtherIsInt64,
  91.     cmpGreaterOrEqualInt64        = cmpGreaterOrEqual     | typeOtherIsInt64,
  92.     cmpLessInt64                = cmpLess                 | typeOtherIsInt64,
  93.     cmpLessOrEqualInt64            = cmpLessOrEqual         | typeOtherIsInt64,
  94.     cmpGreaterInt64                = cmpGreater             | typeOtherIsInt64,
  95.  
  96.     cmpNotEqualLong                = cmpNotEqual             | typeOtherIsLong,
  97.     cmpEqualLong                = cmpEqual                 | typeOtherIsLong,
  98.     cmpGreaterOrEqualLong        = cmpGreaterOrEqual     | typeOtherIsLong,
  99.     cmpLessLong                    = cmpLess                 | typeOtherIsLong,
  100.     cmpLessOrEqualLong            = cmpLessOrEqual         | typeOtherIsLong,
  101.     cmpGreaterLong                = cmpGreater             | typeOtherIsLong,
  102.  
  103.     cmpNotEqualUnsignedLong        = cmpNotEqual             | typeOtherIsULong,
  104.     cmpEqualUnsignedLong        = cmpEqual                 | typeOtherIsULong,
  105.     cmpGreaterOrEqualUnsignedLong= cmpGreaterOrEqual     | typeOtherIsULong,
  106.     cmpLessUnsignedLong            = cmpLess                 | typeOtherIsULong,
  107.     cmpLessOrEqualUnsignedLong    = cmpLessOrEqual         | typeOtherIsULong,
  108.     cmpGreaterUnsignedLong        = cmpGreater             | typeOtherIsULong
  109.     };
  110.  
  111. // I used my own defin here in so that all of the math is based on 
  112. // the one assumption of 32 bit longs. Didn't want this to partially
  113. // work for other sizes.
  114. #define MAXULONG ((2 ^ 32) - 1)
  115.  
  116. //
  117. // Old versions of Types.h use 'wide' instead of 'SInt64'
  118. // (the #ifndef doesn't seem to work, but the redefinition is okay;
  119. // I left the #ifndef in for clarity.)
  120. //
  121. #ifndef SInt64
  122. typedef wide SInt64;
  123. #endif
  124.  
  125.  
  126. //========================================================================================
  127. // CLASS Int64
  128. //
  129. // int is the natural type for the value 0 {ARM, pg 324}, so TWide
  130. // has a number of conversion operators from integer types so that
  131. // there is never any ambiguity {upon which the compiler would barf!}.
  132. //
  133. // For instance, if there were no TWide(int) the compiler would try to
  134. // match “TWide aWide = 0;” with both TWide(long) and TWide(unsigned long),
  135. // both of which are conversions, yielding an ambiguous state.
  136. //========================================================================================
  137.  
  138. class Int64
  139.     {
  140.  
  141.     //
  142.     // --- Methods -------------------------------------------------------------------------------------
  143.     //
  144. public:
  145.             Int64();
  146.             Int64(int i);
  147.             Int64(SInt32 l);
  148.             Int64(UInt32 l);
  149.             Int64(UInt32 high,UInt32 low);
  150.             Int64(SInt64);
  151.             
  152.             operator SInt32() const;
  153.             operator UInt32() const;
  154.             operator double() const;
  155.  
  156.             UInt32 High32();
  157.             UInt32 Low32();
  158.  
  159.     Int64&                operator =(const Int64&);
  160.     Int64&                operator =(int);                // to convert from zero
  161.     Int64&                operator =(SInt32);                // to convert non-zero signed values
  162.     Int64&                operator =(UInt32);                // to convert non-zero unsigned values
  163.     Int64&                operator =(SInt64);
  164.     
  165.     Int64                operator +(const Int64&) const;
  166.     Int64                operator -(const Int64&) const;
  167.     Int64                operator *(const Int64&) const;
  168.     Int64                operator /(const Int64&) const;
  169.     Int64                operator >>(const Int64&) const;
  170.     Int64                operator <<(const Int64&) const;
  171.  
  172.     //
  173.     // Because of the way Int64's are passed around and made into temporaries these 
  174.     // “operate and assign” functions are more efficient than the above ones.
  175.     //
  176.     Int64&                operator +=(const Int64&);
  177.     Int64&                operator -=(const Int64&);
  178.     Int64&                operator >>=(const Int64&);
  179.     Int64&                operator <<=(const Int64&);
  180.     Int64&                operator *=(const Int64&);
  181.     Int64&                operator &=(const Int64&);
  182.  
  183.     Boolean             operator !=(const Int64&) const;
  184.     Boolean             operator ==(const Int64&) const;
  185.     Boolean             operator >=(const Int64&) const;
  186.     Boolean             operator <(const Int64&) const;
  187.     Boolean             operator <=(const Int64&) const;
  188.     Boolean             operator >(const Int64&) const;
  189.     
  190.                         operator SInt64() { return fSInt64; }
  191.     
  192.     Boolean                FitsInLong() const;
  193.     Boolean                FitsInUnsignedLong() const;
  194.  
  195. protected:
  196.     static const Int64* IntuitOtherOperand(SInt16 operation, const void* other, Int64* storage);
  197.     Int64                Operation(SInt16 operation, const void* other) const;
  198.     Boolean                Comparison(SInt16 comparison, const void* otherP) const;
  199.  
  200.     //
  201.     // --- Fields -------------------------------------------------------------------------------------
  202.     //
  203.     SInt64                fSInt64;
  204.     };
  205.  
  206. //inline Boolean operator < (SInt32 l, const Int64& i64) { return (i64 > l); }
  207.  
  208. inline UInt32 Int64::High32()     { return fSInt64.hi;     }
  209. inline UInt32 Int64::Low32()     { return fSInt64.lo;     }
  210.  
  211. //
  212. // Inlines
  213. //
  214.  
  215. //----------------------------------------------------------------------------------------
  216. // Int64::FitsInLong: 
  217. //
  218. // to legally crunch a signed 63 into a signed 31 bit number, the high 32 bits
  219. // must be only sign extension { zero or negative one }, and the high bit of the low
  220. // 32 bits must equal the sign, otherwise that 32nd bit is being used to store a
  221. // component of the value.
  222. //----------------------------------------------------------------------------------------
  223. inline Boolean    Int64::FitsInLong() const
  224.     {
  225.     Boolean result = false;                    // assume large to be safe
  226.     
  227.     if (fSInt64.hi == 0)                        // could be a  positive number, 
  228.         result = (*(SInt32*)&fSInt64.lo >= 0);    // can it fit in 31 bits?
  229.     else if (fSInt64.hi == -1)                    // could be a negative number
  230.         result = (*(SInt32*)&fSInt64.lo < 0);        // can it fit in 31 bits?
  231.     
  232.     // the high 32 bits was not a sign extension so this quantity can't fit in 32
  233.     
  234.     return result;
  235.     }
  236.  
  237. //----------------------------------------------------------------------------------------
  238. // Int64::FitsInUnsignedLong: 
  239. //----------------------------------------------------------------------------------------
  240. inline Boolean    Int64::FitsInUnsignedLong() const
  241.     {
  242.     
  243.     //
  244.     // if high 32 is a sign extension then true
  245.     //
  246.     // notice that wrapping around is made legal
  247.     // I think that this is good, but I could be posessed by the devil
  248.     // -Dave0
  249.     //
  250.     return (fSInt64.hi == 0) || (fSInt64.hi == -1);
  251.     }
  252.  
  253. //----------------------------------------------------------------------------------------
  254. // Int64::=: 
  255. //
  256. // WARNING: DO NOT declare an Int64 inside this method and assign another Int64 to it,
  257. //            or you'll recurse forever.  Me and Max, we've been there.  Done that. -andy
  258. //----------------------------------------------------------------------------------------
  259. inline Int64& Int64::operator =(const Int64& amount)            
  260.     {
  261.     fSInt64.hi = amount.fSInt64.hi;
  262.     fSInt64.lo  = amount.fSInt64.lo;
  263.  
  264.     return *this;
  265.     } 
  266.  
  267. //----------------------------------------------------------------------------------------
  268. // Int64::=: 
  269. //----------------------------------------------------------------------------------------
  270. inline Int64&     Int64::operator =(int amount)                    
  271.     { 
  272.     fSInt64.lo  = amount;
  273.     fSInt64.hi = 0;
  274.  
  275.     if (amount < 0)
  276.         fSInt64.hi =  -1;
  277.  
  278.     return *this;
  279.     } 
  280.     
  281.  
  282. //----------------------------------------------------------------------------------------
  283. // Int64::=: 
  284. //----------------------------------------------------------------------------------------
  285. inline Int64&     Int64::operator =(SInt32 amount)                    
  286.     { 
  287.     fSInt64.lo  = amount;
  288.     fSInt64.hi = 0;
  289.  
  290.     if (amount < 0)
  291.         fSInt64.hi =  -1;
  292.  
  293.     return *this;
  294.     }
  295.     
  296.  
  297. //----------------------------------------------------------------------------------------
  298. // Int64::=: 
  299. //----------------------------------------------------------------------------------------
  300. inline Int64&     Int64::operator =(UInt32 amount)            
  301.     { 
  302.     fSInt64.lo  = amount;
  303.     fSInt64.hi = 0;
  304.  
  305.     return *this;
  306.     } 
  307.  
  308. //----------------------------------------------------------------------------------------
  309. // Int64::=: 
  310. //----------------------------------------------------------------------------------------
  311. inline Int64&     Int64::operator =(SInt64 amount)            
  312.     { 
  313.     fSInt64.lo  = amount.lo;
  314.     fSInt64.hi = amount.hi;
  315.  
  316.     return *this;
  317.     } 
  318.  
  319. //----------------------------------------------------------------------------------------
  320. // Int64::Int64: 
  321. //----------------------------------------------------------------------------------------
  322. inline Int64::Int64()                    
  323.     {
  324.     ;
  325.     }
  326.     
  327. //----------------------------------------------------------------------------------------
  328. // Int64::Int64: 
  329. //----------------------------------------------------------------------------------------
  330. inline Int64::Int64(int amount)        
  331.     {
  332.     fSInt64.lo  = amount;
  333.     fSInt64.hi = 0;
  334.  
  335.     if (amount < 0)
  336.         fSInt64.hi =  -1;
  337.     }
  338.  
  339.  
  340. //----------------------------------------------------------------------------------------
  341. // Int64::Int64: 
  342. //----------------------------------------------------------------------------------------
  343. inline Int64::Int64(SInt32 amount)            
  344.     {
  345.     fSInt64.lo  = amount;
  346.     fSInt64.hi = 0;
  347.  
  348.     if (amount < 0)
  349.         fSInt64.hi =  -1;
  350.     } 
  351.  
  352.  
  353. //----------------------------------------------------------------------------------------
  354. // Int64::Int64: 
  355. //----------------------------------------------------------------------------------------
  356. inline Int64::Int64(UInt32 amount)
  357.     {
  358.     fSInt64.hi = 0;
  359.     fSInt64.lo  = amount;
  360.     }
  361.     
  362.  
  363. //----------------------------------------------------------------------------------------
  364. // Int64::Int64: 
  365. //----------------------------------------------------------------------------------------
  366. inline Int64::Int64(UInt32 high,UInt32 low)    
  367.     {
  368.     fSInt64.hi = high;
  369.     fSInt64.lo = low;
  370.     }
  371.  
  372. //----------------------------------------------------------------------------------------
  373. // Int64::Int64: 
  374. //----------------------------------------------------------------------------------------
  375. inline Int64::Int64(SInt64 amount)    
  376.     {
  377.     fSInt64.hi = amount.hi;
  378.     fSInt64.lo = amount.lo;
  379.     }
  380.  
  381.  
  382. //----------------------------------------------------------------------------------------
  383. // Int64::SInt32: 
  384. //----------------------------------------------------------------------------------------
  385. inline Int64::operator SInt32() const
  386.     {
  387.     if (FitsInLong())
  388.         return fSInt64.lo;
  389.     else
  390.         return kInt64CanNotFitIn32Bits;
  391.     }
  392.  
  393.  
  394. //----------------------------------------------------------------------------------------
  395. // Int64::UInt32: 
  396. //----------------------------------------------------------------------------------------
  397. inline Int64::operator UInt32() const
  398.     {
  399.     if (FitsInUnsignedLong())
  400.         return fSInt64.lo;
  401.     else
  402.         return kInt64CanNotFitIn32Bits;
  403.     }
  404.  
  405.  
  406. //----------------------------------------------------------------------------------------
  407. // Int64::double: 
  408. //----------------------------------------------------------------------------------------
  409. inline Int64::operator double() const
  410.     {
  411.     double result;
  412.     
  413.     result  = fSInt64.hi;
  414.     result *= 4294967296.0;                    // 2 ^ 32 (done on Tom's HP calculator, no less)
  415.     
  416.     result += double(fSInt64.lo);
  417.     
  418.     return result;
  419.     }    
  420.  
  421. //----------------------------------------------------------------------------------------
  422. // Int64::+=: 
  423. //----------------------------------------------------------------------------------------
  424. inline Int64&     Int64::operator +=(const Int64& amount)            
  425.     { 
  426.     Int64 result;
  427.     
  428.     result  = Operation(opAddInt64, &amount);         
  429.     fSInt64.hi = result.High32();
  430.     fSInt64.lo  = result.Low32();
  431.  
  432.     return *this;
  433.     } // Int64::+= 
  434.     
  435.  
  436. //----------------------------------------------------------------------------------------
  437. // Int64::-=: 
  438. //----------------------------------------------------------------------------------------
  439. inline Int64&    Int64::operator -=(const Int64& amount)            
  440.     { 
  441.     Int64 result;
  442.     
  443.     result  = Operation(opSubtractInt64, &amount);     
  444.     fSInt64.hi = result.High32();
  445.     fSInt64.lo  = result.Low32();
  446.  
  447.     return *this;
  448.     } // Int64::-= 
  449.     
  450.  
  451. //----------------------------------------------------------------------------------------
  452. // Int64::>>=: 
  453. //----------------------------------------------------------------------------------------
  454. inline Int64&     Int64::operator >>=(const Int64& amount)        
  455.     { 
  456.     Int64 result;
  457.     
  458.     result  = Operation(opShiftRightInt64, &amount);
  459.     fSInt64.hi = result.High32();
  460.     fSInt64.lo  = result.Low32();
  461.  
  462.     return *this;
  463.     } // Int64::>>= 
  464.     
  465.  
  466. //----------------------------------------------------------------------------------------
  467. // Int64::<<=: 
  468. //----------------------------------------------------------------------------------------
  469. inline Int64&     Int64::operator <<=(const Int64& amount)        
  470.     { 
  471.     Int64 result;
  472.     
  473.     result  = Operation(opShiftLeftInt64, &amount); 
  474.     fSInt64.hi = result.High32();
  475.     fSInt64.lo  = result.Low32();
  476.  
  477.     return *this;
  478.     } // Int64::<<= 
  479.     
  480.  
  481. //----------------------------------------------------------------------------------------
  482. // Int64::*=: 
  483. //----------------------------------------------------------------------------------------
  484. inline Int64&     Int64::operator *=(const Int64& amount)            
  485.     { 
  486.     Int64 result;
  487.     
  488.     result  = Operation(opMultiplyInt64, &amount);     
  489.     fSInt64.hi = result.High32();
  490.     fSInt64.lo  = result.Low32();
  491.  
  492.     return *this;
  493.     } // Int64::*= 
  494.  
  495.  
  496. //----------------------------------------------------------------------------------------
  497. // Int64::operator &=: 
  498. //----------------------------------------------------------------------------------------
  499. inline Int64& Int64::operator &=(const Int64& amount)            
  500.     {
  501.     fSInt64.hi     = fSInt64.hi & amount.fSInt64.hi;
  502.     fSInt64.lo        = fSInt64.lo  & amount.fSInt64.lo;
  503.  
  504.     return *this;
  505.     }
  506.  
  507.  
  508. inline Int64    Int64::operator +(const Int64& amount) const    { return Operation(opAddInt64, &amount);                     }
  509. inline Int64     Int64::operator -(const Int64& amount) const    { return Operation(opSubtractInt64, &amount);                 }
  510. inline Int64    Int64::operator *(const Int64& amount) const    { return Operation(opMultiplyInt64, &amount);                 }
  511. inline Int64     Int64::operator /(const Int64& amount) const    { return Operation(opDivideInt64, &amount);                 }
  512. inline Int64     Int64::operator >>(const Int64& amount) const    { return Operation(opShiftRightInt64, &amount);             }
  513. inline Int64     Int64::operator <<(const Int64& amount) const    { return Operation(opShiftLeftInt64, &amount);                 }
  514.  
  515. inline Boolean     Int64::operator !=(const Int64& b) const        { return Comparison(cmpNotEqualInt64, &b);                     }
  516. inline Boolean     Int64::operator ==(const Int64& b) const        { return Comparison(cmpEqualInt64, &b);                     }
  517. inline Boolean     Int64::operator >=(const Int64& b) const        { return Comparison(cmpGreaterOrEqualInt64, &b);             }
  518. inline Boolean     Int64::operator <(const Int64& b) const            { return Comparison(cmpLessInt64, &b);                         }
  519. inline Boolean     Int64::operator <=(const Int64& b) const        { return Comparison(cmpLessOrEqualInt64, &b);                 }
  520. inline Boolean     Int64::operator >(const Int64& b) const            { return Comparison(cmpGreaterInt64, &b);                     }
  521.  
  522.  
  523. #endif // REZ
  524. #endif // Int64_h
  525.